package service

import (
	"common/biz"
	"common/logs"
	"common/utils"
	"context"
	"core/dao"
	"core/models/db"
	"core/models/entity"
	"core/repo"
	"framework/msError"
	"github.com/shopspring/decimal"
	"hall/models/request"
	hall "hall/models/response"
	"math"
	"sort"
	"time"
)

type WarehouseService struct {
	warehouseDao *dao.WarehouseDao
	userDao      *dao.UserDao
	typeDao      *dao.TypeDao
	configDao    *dao.ConfigDao
}

func (w *WarehouseService) WarehouseList(ctx context.Context, uid uint, req *request.WarehouseScreen) (*[]hall.MaterialData, *[]hall.CardData, *[]hall.EquipData) {
	materialData := make([]hall.MaterialData, 0)
	if req.TypeThree == 0 || req.TypeThree == 2 {
		material := w.warehouseDao.GetMaterial(ctx, uid, req)
		for _, v := range *material {
			if (v.Num <= 0) || !v.Types.IsShow {
				continue
			}
			donates := make([]hall.Donate, 0)
			for _, val := range v.Donate {
				odds := decimal.NewFromFloat(float64(val.Odds))
				odds = odds.Div(decimal.NewFromFloat(100))
				oddsData, _ := odds.Float64()
				var donate hall.Donate
				if val.Type == 1 {
					donate = hall.Donate{
						Type:     val.Type,
						LinkID:   val.LinkID,
						LinkName: val.LinkRole.Name,
						LinkImg:  val.LinkRole.Img,
						Num:      val.Num,
						Odds:     oddsData,
					}
				} else {
					donate = hall.Donate{
						Type:     val.Type,
						LinkID:   val.LinkID,
						LinkName: val.LinkType.Name,
						LinkImg:  val.LinkType.Img,
						Num:      val.Num,
						Odds:     oddsData,
					}
				}
				donates = append(donates, donate)
			}
			num := float64(v.Num)
			if v.Types.Types == 6 {
				num = utils.DecimalIntDiv(v.Num, v.Types.Val)
			}
			materialData = append(materialData, hall.MaterialData{
				WID:         v.ID,
				TypeID:      v.TypeID,
				TypeName:    v.Types.Name,
				TypeImg:     v.Types.Img,
				DescImg:     v.Types.DescImg,
				TypeType:    v.Types.Type,
				TypeTypes:   v.Types.Types,
				TypeModule:  v.Types.Module,
				TypeDesc:    v.Types.Desc,
				Num:         num,
				Donate:      donates,
				IsSell:      v.Types.IsSell,
				IsTransfer:  v.Types.IsTransfer,
				TransferFee: w.GetRoleTransferFee(ctx, uid),
			})
		}
	}
	cardData := make([]hall.CardData, 0)
	if req.TypeThree == 0 || req.TypeThree == 1 {
		cards := w.warehouseDao.GetCard(ctx, uid, req)
		card := *cards
		sort.Sort(db.WarehouseCardsHasOneType(card))
		typeInfo := w.typeDao.GetInfo(ctx, 11)
		for _, v := range card {
			cardData = append(cardData, hall.CardData{
				WID:         v.ID,
				TypeID:      v.TypeID,
				TypeName:    v.Types.Name,
				TypeImg:     v.Types.Img,
				DescImg:     v.Types.DescImg,
				TypeModule:  v.Types.Module,
				TypeDesc:    v.Types.Desc,
				TypeType:    v.Types.Type,
				TypeTypes:   v.Types.Types,
				SyOutput:    utils.DecimalIntDiv(v.Num, typeInfo.Val),
				TotalOutput: utils.DecimalIntDiv(v.TypeCard.TotalOutput, typeInfo.Val),
				OutputRate:  utils.DecimalIntDiv(v.Rate, typeInfo.Val),
				Level:       v.TypeCard.Level,
				IsNew:       v.IsNew,
				Token:       v.TokenID,
				Hax:         v.Hax,
				IsSell:      v.Types.IsSell,
				IsTransfer:  v.Types.IsTransfer,
			})
		}
	}
	equipData := make([]hall.EquipData, 0)
	if req.TypeThree == 0 || req.TypeThree == 3 {
		equip := w.warehouseDao.GetEquip(ctx, uid, req)
		for _, v := range *equip {
			equipData = append(equipData, hall.EquipData{
				WID:        v.ID,
				TypeID:     v.TypeID,
				TypeName:   v.Types.Name,
				TypeImg:    v.Types.Img,
				DescImg:    v.Types.DescImg,
				TypeModule: v.Types.Module,
				TypeDesc:   v.Types.Desc,
				TypeType:   v.Types.Type,
				TypeTypes:  v.Types.Types,
				IsNew:      v.IsNew,
				Num:        v.Conf.Term,
				SyNum:      v.SyNum,
				Increase:   utils.DecimalIntDiv(v.Conf.Increase, 100),
				IsSell:     v.Types.IsSell,
				IsTransfer: v.Types.IsTransfer,
			})
		}
	}
	return &materialData, &cardData, &equipData
}

func (w *WarehouseService) GetInfo(ctx context.Context, uid uint, req *request.WarehouseGetInfo) any {
	var info any
	switch req.Type {
	case 2:
		data := w.warehouseDao.GetMaterialInfo(ctx, uid, req.ID)
		donates := make([]hall.Donate, 0)
		for _, val := range data.Donate {
			odds := decimal.NewFromFloat(float64(val.Odds))
			odds = odds.Div(decimal.NewFromFloat(100))
			oddsData, _ := odds.Float64()
			var donate hall.Donate
			if val.Type == 1 {
				donate = hall.Donate{
					Type:     val.Type,
					LinkID:   val.LinkID,
					LinkName: val.LinkRole.Name,
					LinkImg:  val.LinkRole.Img,
					Num:      val.Num,
					Odds:     oddsData,
				}
			} else {
				donate = hall.Donate{
					Type:     val.Type,
					LinkID:   val.LinkID,
					LinkName: val.LinkType.Name,
					LinkImg:  val.LinkType.Img,
					Num:      val.Num,
					Odds:     oddsData,
				}
			}
			donates = append(donates, donate)
		}
		num := float64(data.Num)
		if data.Types.Types == 6 {
			num = utils.DecimalIntDiv(data.Num, data.Types.Val)
		}
		isTransfer := data.Types.IsTransfer
		if isTransfer {
			user := w.userDao.GetUserOfRole(ctx, uid)
			if user != nil {
				if data.Types.Types == 9 {
					isTransfer = user.Role.IsCard
					//if user.Role.ChamberMember.ID == 0 {
					//	isTransfer = false
					//}
				} else {
					isTransfer = user.Role.IsTransfer
					if user.Role.OffTransfer {
						isTransfer = false
					}
				}
			}
		}
		info = hall.MaterialData{
			WID:         data.ID,
			TypeID:      data.TypeID,
			TypeName:    data.Types.Name,
			TypeImg:     data.Types.Img,
			DescImg:     data.Types.DescImg,
			TypeType:    data.Types.Type,
			TypeTypes:   data.Types.Types,
			TypeModule:  data.Types.Module,
			TypeDesc:    data.Types.Desc,
			Num:         num,
			Donate:      donates,
			IsSell:      data.Types.IsSell,
			IsTransfer:  isTransfer,
			IsExtract:   data.Types.IsExtract,
			TransferFee: w.GetRoleTransferFee(ctx, uid),
		}
	case 1:
		data := w.warehouseDao.GetCardInfo(ctx, uid, req.ID)
		typeInfo := w.typeDao.GetInfo(ctx, 11)
		isTransfer := data.Types.IsTransfer
		if isTransfer {
			user := w.userDao.GetUserOfRole(ctx, uid)
			if user != nil {
				isTransfer = user.Role.IsTransfer
			}
		}
		info = hall.CardData{
			WID:         data.ID,
			TypeID:      data.TypeID,
			TypeName:    data.Types.Name,
			TypeImg:     data.Types.Img,
			DescImg:     data.Types.DescImg,
			TypeModule:  data.Types.Module,
			TypeDesc:    data.Types.Desc,
			TypeType:    data.Types.Type,
			TypeTypes:   data.Types.Types,
			SyOutput:    utils.DecimalIntDiv(data.Num, typeInfo.Val),
			TotalOutput: utils.DecimalIntDiv(data.TypeCard.TotalOutput, typeInfo.Val),
			OutputRate:  utils.DecimalIntDiv(data.Rate, typeInfo.Val),
			Level:       data.TypeCard.Level,
			IsNew:       data.IsNew,
			Token:       data.TokenID,
			Hax:         data.Hax,
			IsSell:      data.Types.IsSell,
			IsTransfer:  isTransfer,
		}
	case 3:
		data := w.warehouseDao.GetEquipInfo(ctx, uid, req.ID)
		isTransfer := data.Types.IsTransfer
		if isTransfer {
			user := w.userDao.GetUserOfRole(ctx, uid)
			if user != nil {
				isTransfer = user.Role.IsTransfer
			}
		}
		info = hall.EquipData{
			WID:        data.ID,
			TypeID:     data.TypeID,
			TypeName:   data.Types.Name,
			TypeImg:    data.Types.Img,
			DescImg:    data.Types.DescImg,
			TypeModule: data.Types.Module,
			TypeDesc:   data.Types.Desc,
			TypeType:   data.Types.Type,
			TypeTypes:  data.Types.Types,
			IsNew:      data.IsNew,
			Num:        data.Conf.Term,
			SyNum:      data.SyNum,
			Increase:   utils.DecimalIntDiv(data.Conf.Increase, 100),
			IsSell:     data.Types.IsSell,
			IsTransfer: isTransfer,
		}
	}
	return info
}

func (w *WarehouseService) GetMaterial(ctx context.Context, uid, typeID uint) *db.WarehouseMaterialHasOneType {
	return w.warehouseDao.GetMaterialInfoByTypeID(ctx, uid, typeID)
}

func (w *WarehouseService) StarGame(user []uint, score int64, roomID string) error {
	return w.warehouseDao.StarGame(user, score, roomID)
}

func (w *WarehouseService) WarehouseMaterial(ctx context.Context, uid uint, typeID uint) *hall.MaterialData {
	data := w.warehouseDao.GetMaterialInfoByTypeID(ctx, uid, typeID)
	donates := make([]hall.Donate, 0)
	for _, val := range data.Donate {
		odds := utils.DecimalIntByFloat(val.Odds)
		if val.TypeID == 11 {
			odds = utils.DecimalFloatDiv(odds, utils.DecimalIntByFloat(val.LinkType.Val))
		}
		var donate hall.Donate
		if val.Type == 1 {
			donate = hall.Donate{
				Type:     val.Type,
				LinkID:   val.LinkID,
				LinkName: val.LinkRole.Name,
				LinkImg:  val.LinkRole.Img,
				Num:      val.Num,
				Odds:     odds,
			}
		} else {
			donate = hall.Donate{
				Type:     val.Type,
				LinkID:   val.LinkID,
				LinkName: val.LinkType.Name,
				LinkImg:  val.LinkType.Img,
				Num:      val.Num,
				Odds:     odds,
			}
		}
		donates = append(donates, donate)
	}
	num := float64(data.Num)
	if data.TypeID == 11 {
		num = utils.DecimalIntDiv(data.Num, data.Types.Val)
	}
	return &hall.MaterialData{
		WID:        data.ID,
		TypeID:     data.TypeID,
		TypeName:   data.Types.Name,
		TypeImg:    data.Types.Img,
		TypeType:   data.Types.Type,
		TypeTypes:  data.Types.Types,
		TypeModule: data.Types.Module,
		TypeDesc:   data.Types.Desc,
		Num:        num,
		Donate:     donates,
	}
}

func (w *WarehouseService) OpenCardPackage(ctx context.Context, uid, id uint) (*[]hall.CardData, int, any, *msError.Error) {
	data := w.warehouseDao.GetMaterialInfo(ctx, uid, id)
	if data == nil || data.ID == 0 {
		logs.Error("[warehouseHandler]用户%d OpenCardPackage err:未查询到数据,res=%v", data.UID, data)
		return nil, 0, "", biz.RequestDataError
	}
	if data.Num < 1 {
		logs.Error("[warehouseHandler]用户%d OpenCardPackage err:数量不足,res=%v", data.UID, data)
		return nil, 0, "", biz.NotEnoughGold
	}
	if data.Types.Types != 9 {
		logs.Error("[warehouseHandler]用户%d OpenCardPackage err:类型不是卡包,res=%v", data.UID, data)
		return nil, 0, "", biz.RequestDataError
	}
	cardPackage, types, donate, err := w.warehouseDao.OpenCardPackage(ctx, data)
	cardArr := make([]hall.CardData, 0)
	typeInfo := w.typeDao.GetInfo(ctx, 11)
	for _, wid := range cardPackage {
		info := w.warehouseDao.GetCardInfo(ctx, uid, wid)
		cardArr = append(cardArr, hall.CardData{
			WID:         info.ID,
			TypeID:      info.TypeID,
			TypeName:    info.Types.Name,
			TypeImg:     info.Types.Img,
			DescImg:     info.Types.DescImg,
			TypeModule:  info.Types.Module,
			TypeDesc:    info.Types.Desc,
			TypeType:    info.Types.Type,
			TypeTypes:   info.Types.Types,
			SyOutput:    utils.DecimalIntDiv(info.Num, typeInfo.Val),
			TotalOutput: utils.DecimalIntDiv(info.TypeCard.TotalOutput, typeInfo.Val),
			OutputRate:  utils.DecimalIntDiv(info.Rate, typeInfo.Val),
			Level:       info.TypeCard.Level,
			IsNew:       info.IsNew,
			Token:       info.TokenID,
			Hax:         info.Hax,
		})
	}
	return &cardArr, types, donate, err
}

func (w *WarehouseService) WarehouseCardNext(ctx context.Context, uid uint, id uint) *hall.CardNextInfo {
	data := w.warehouseDao.GetCardInfo(ctx, uid, id)
	if data == nil || data.ID == 0 {
		logs.Error("[warehouseHandler]用户%d WarehouseCardNext err:未查询到数据,res=%v", data.UID, data)
		return nil
	}
	if data.TypeCard.Level >= 6 {
		logs.Error("[warehouseHandler]用户%d WarehouseCardNext err:等级已满,res=%v", data.UID, data)
		return nil
	}
	if data.IsUse {
		logs.Error("[warehouseHandler]用户%d WarehouseCardNext err:卡牌已使用,res=%v", data.UID, data)
		return nil
	}
	types := w.typeDao.GetInfo(ctx, 11)
	nextTypeCard := w.typeDao.GetCardNext(ctx, data.TypeID, data.TypeCard.Level+1)
	consumeNum := utils.DecimalIntByFloat(nextTypeCard.ConsumeNum)
	if nextTypeCard.ConsumeTypeID == 11 {
		consumeNum = utils.DecimalIntDiv(nextTypeCard.ConsumeNum, types.Val)
	}
	donation := utils.DecimalIntDiv(nextTypeCard.TotalOutput-data.TypeCard.TotalOutput+data.Num, types.Val)
	typeInit := w.typeDao.GetCardInit(ctx, data.TypeID)
	count := w.warehouseDao.GetCardTypeCount(ctx, id, uid, typeInit.ID)
	info := &hall.CardNextInfo{
		TypeName:           data.Types.Name,
		TypeImg:            data.Types.Img,
		DescImg:            data.Types.DescImg,
		TypeModule:         data.Types.Module,
		TypeDesc:           data.Types.Desc,
		ConsumeTypeID:      nextTypeCard.ConsumeTypeID,
		ConsumeTypeName:    nextTypeCard.ConsumeType.Name,
		ConsumeTypeImg:     nextTypeCard.ConsumeType.Img,
		ConsumeTypeModule:  nextTypeCard.ConsumeType.Module,
		ConsumeNum:         consumeNum,
		NextLevel:          nextTypeCard.Level,
		NextLevelDonation:  donation,
		NextLevelOutput:    utils.DecimalIntDiv(nextTypeCard.Output, types.Val),
		NextLevelOutputMax: utils.DecimalIntDiv(nextTypeCard.OutputMax, types.Val),
		UpgradeNum:         nextTypeCard.UpgradeCardNum,
		SimilarCardCount:   count,
	}
	return info
}

func (w *WarehouseService) WarehouseCardUpgrade(ctx context.Context, uid uint, id uint) *msError.Error {
	data := w.warehouseDao.GetCardInfo(ctx, uid, id)
	if data == nil || data.ID == 0 {
		logs.Error("[warehouseHandler]用户%d WarehouseCardUpgrade err:未查询到数据,res=%v", data.UID, data)
		return biz.RequestDataError
	}
	if data.TypeCard.Level >= 5 {
		logs.Error("[warehouseHandler]用户%d WarehouseCardUpgrade err:等级已满,res=%v", data.UID, data)
		return biz.RequestDataError
	}
	if data.IsUse {
		logs.Error("[warehouseHandler]用户%d WarehouseCardUpgrade err:卡牌已使用,res=%v", data.UID, data)
		return biz.RequestDataError
	}
	nextTypeCard := w.typeDao.GetCardNext(ctx, data.TypeID, data.TypeCard.Level+1)
	if nextTypeCard == nil || nextTypeCard.ID == 0 {
		logs.Error("[warehouseHandler]用户%d WarehouseCardUpgrade err:等级已满,res=%v", data.UID, data)
		return biz.RequestDataError
	}
	typeInit := w.typeDao.GetCardInit(ctx, data.TypeID)
	count := w.warehouseDao.GetCardTypeCount(ctx, id, uid, typeInit.ID)
	if typeInit.TotalOutput/2 > data.Num {
		logs.Error("[warehouseHandler]用户%d WarehouseCardUpgrade err:剩余产量不足总量的一半,res=%v", data.UID, data)
		return biz.UpgradeCardNotHalf
	}
	if count < nextTypeCard.UpgradeCardNum {
		logs.Error("[warehouseHandler]用户%d WarehouseCardUpgrade err:升级卡牌数量不足,res=%v", data.UID, data)
		return biz.NotEnoughGold
	}
	return w.warehouseDao.WarehouseCardUpgrade(ctx, data, nextTypeCard)
}

func (w *WarehouseService) WarehouseGoldTransfer(ctx context.Context, uid uint, req *request.WarehouseGoldTransfer) *msError.Error {
	user := w.userDao.GetUserOfRole(ctx, uid)
	if user == nil || user.ID == 0 {
		logs.Error("[warehouseHandler]用户%d WarehouseGoldTransfer err:未查询到自己信息,res=%v", uid, user)
		return biz.AccountNotExist
	}
	if !user.Role.IsTransfer {
		logs.Error("[warehouseHandler]用户%d WarehouseGoldTransfer err:没有开启转出功能,res=%v", uid, user)
		return biz.NotOpenTransfer
	}
	if user.TransactionPassword == "" {
		logs.Error("[warehouseHandler]用户%d WarehouseGoldTransfer err:交易密码为空 req=%v", uid, req)
		return biz.TransactionPasswordEmpty
	}
	if user.TransactionPassword != utils.Md5Password(req.Pwd) {
		logs.Error("[warehouseHandler]用户%d WarehouseGoldTransfer err:交易密码错误,res=%v", uid, req.Pwd)
		return biz.TransactionPasswordError
	}
	other := w.userDao.GetInviteCodeByUid(ctx, req.Phone)
	otherUser := w.userDao.GetUserOfRole(ctx, other)
	if otherUser == nil || otherUser.ID == 0 {
		logs.Error("[warehouseHandler]用户%d WarehouseGoldTransfer err:通过手机号未获取到对方信息,res=%v", uid, otherUser)
		return biz.AccountNotExist
	}
	if uid == other {
		logs.Error("[warehouseHandler]用户%d WarehouseGoldTransfer err:不能给自己转,res=%v", uid, other)
		return biz.AccountNotMy
	}
	if req.Num <= 0 {
		logs.Error("[warehouseHandler]用户%d WarehouseGoldTransfer err:转出数量必须大于0,res=%v", uid, req.Num)
		return biz.ZeroError
	}
	if req.TypeID == 12 {
		if req.Num%100 != 0 {
			logs.Error("[warehouseHandler]用户%d WarehouseGoldTransfer err:转出数量必须是100的倍数,res=%v", uid, req.Num)
			return biz.NumMustHundredMultiple
		}
	} else if req.TypeID == 11 {
		if user.Role.OffTransfer {
			logs.Error("[warehouseHandler]用户%d WarehouseGoldTransfer err:该账户禁止转账,res=%v", uid, user)
			return biz.OffTransfer
		}
	} else if req.TypeID == 14 {
		//顶商才能赠送
		if user.Role.ChamberMember.ID == 0 {
			logs.Error("[warehouseHandler]用户%d WarehouseGoldTransfer err:该账户不是商会成员,无权限转转赠,res=%v", uid, user)
			return biz.NotJurisdictionTransfer
		}
	}
	transferFee := w.GetRoleTransferFee(ctx, uid)
	var divideInto []db.UserHasOneRole
	//手续费不为空 && 对方是商会成员 && 商会成员上级有人
	//if transferFee > 0 && otherUser.Role.ChamberMember.LevelID != 0 && otherUser.Role.ChamberMember.PID != 0 {
	//	pid := w.userDao.GetChamberMemberByPID(ctx, otherUser.Role.ChamberMember.PID)
	//	userChamber := w.userDao.GetUserOfRole(ctx, pid)
	//	divideInto = append(divideInto, *userChamber)
	//	if userChamber.Role.ChamberMember.PID != 0 {
	//		pid = w.userDao.GetChamberMemberByPID(ctx, userChamber.Role.ChamberMember.PID)
	//		userChamber = w.userDao.GetUserOfRole(ctx, pid)
	//		divideInto = append(divideInto, *userChamber)
	//	}
	//}
	err := w.warehouseDao.WarehouseGoldTransfer(ctx, req, user, otherUser, transferFee, &divideInto)
	if err != nil {
		return err
	}
	return nil
}

func (w *WarehouseService) GetRoleTransferFee(ctx context.Context, uid uint) float64 {
	var fee float64
	user := w.userDao.GetUserOfRole(ctx, uid)
	//if user.Role.ChamberMember.LevelID == 0 {
	if user.Role.IsVIP {
		transfer := w.configDao.GetVal(ctx, "vip_transfer_trade_fee")
		fee = utils.DecimalStringByFloat(transfer)
	} else if w.CardBuyCount(ctx, uid) > 0 {
		transfer := w.configDao.GetVal(ctx, "card_transfer_fee")
		fee = utils.DecimalStringByFloat(transfer)
	} else {
		transfer := w.configDao.GetVal(ctx, "transfer_trade_fee")
		fee = utils.DecimalStringByFloat(transfer)
	}
	//}
	return fee
}

func (w *WarehouseService) GetInvestmentCore(ctx context.Context, uid uint) *hall.InvestmentData {
	data := w.warehouseDao.GetInvestmentCore(ctx)
	var res hall.InvestmentData
	for k, v := range *data {
		material := w.WarehouseMaterial(ctx, uid, v.TypeID)
		res.My = append(res.My, *material)
		if k == 0 {
			res.One = hall.InvestmentInfo{
				TypeID:   v.TypeID,
				TypeName: v.Types.Name,
				TypeImg:  v.Types.Img,
				Num:      utils.DecimalIntDiv(v.Num, v.Types.Val),
				Rate:     1,
			}
		} else {
			res.Two = hall.InvestmentInfo{
				TypeID:   v.TypeID,
				TypeName: v.Types.Name,
				TypeImg:  v.Types.Img,
				Num:      utils.DecimalIntByFloat(v.Num),
			}
			res.Two.Rate = utils.DecimalFloatDiv(res.Two.Num, res.One.Num)
			res.Two.Rate = math.Round(res.Two.Rate)
		}
	}
	res.Fee = utils.DecimalStringByFloat(w.configDao.GetVal(ctx, "investment_fee"))
	log := w.warehouseDao.GetInvestmentLog(ctx, 10)
	var investmentLog []hall.InvestmentLog
	types := w.typeDao.GetInfo(ctx, 11)
	for _, v := range *log {
		user := w.userDao.GetUserOfReal(ctx, v.UID)
		num := utils.DecimalIntByFloat(v.Num)
		if v.TypeID == types.ID {
			num = utils.DecimalIntDiv(v.Num, types.Val)
		}
		consumeNum := v.ConsumeNum
		if v.ConsumeTypeID == types.ID {
			consumeNum = utils.DecimalFloatDiv(v.ConsumeNum, utils.DecimalIntByFloat(types.Val))
		}
		investmentLog = append(investmentLog, hall.InvestmentLog{
			Nickname:        utils.UpNickname(user.Role.Nickname),
			TypeName:        v.TypeName,
			TypeImg:         v.TypeImg,
			Num:             num,
			Total:           v.Total,
			ConsumeTypeName: v.ConsumeTypeName,
			ConsumeTypeImg:  v.ConsumeTypeImg,
			ConsumeNum:      consumeNum,
			Dates:           v.AddTime,
		})
	}
	res.Log = investmentLog
	return &res
}

func (w *WarehouseService) InvExchange(ctx context.Context, exchange *entity.InvestmentExchangeLog) *msError.Error {
	return w.warehouseDao.InvExchange(ctx, exchange)
}

func (w *WarehouseService) WarehouseExtract(ctx context.Context, uid uint, req *request.WarehouseExtract) *msError.Error {
	if req.Pwd == "" {
		logs.Error("[warehouseHandler]用户%d WarehouseExtract err:交易密码为空 req=%v", uid, req)
		return biz.TransactionPasswordEmpty
	}
	if req.Name == "" {
		logs.Error("[warehouseHandler]用户%d WarehouseExtract err:提现姓名为空 req=%v", uid, req)
		return biz.NameEmpty
	}
	if req.Code == "" {
		logs.Error("[warehouseHandler]用户%d WarehouseExtract err:提现支付宝账号为空 req=%v", uid, req)
		return biz.BankCardEmpty
	}
	if req.Num <= 0 || req.Num%10 != 0 {
		logs.Error("[warehouseHandler]用户%d WarehouseExtract err:输入金额小于等于0 或不为10的倍数 req=%v", uid, req)
		return biz.ExtractMoneyNotTenMultiple
	}
	user := w.userDao.GetUserOfRole(ctx, uid)
	if user.TransactionPassword == "" {
		logs.Error("[warehouseHandler]用户%d WarehouseGoldTransfer err:交易密码为空 req=%v", uid, req)
		return biz.TransactionPasswordEmpty
	}
	if user.TransactionPassword != utils.Md5Password(req.Pwd) {
		logs.Error("[warehouseHandler]用户%d WarehouseExtract err:交易密码错误 req=%v", uid, req)
		return biz.TransactionPasswordError
	}
	var typeID uint = 28
	material := w.warehouseDao.GetMaterialInfoByTypeID(ctx, uid, typeID)
	if material == nil {
		logs.Error("[warehouseHandler]用户%d WarehouseExtract err:该用户没有该类型 req=%v", uid, req)
		return biz.ExtractMoneyNotEnough
	}
	if material.Num < req.Num {
		logs.Error("[warehouseHandler]用户%d WarehouseExtract err:提现金额不足 req=%v", uid, material)
		return biz.ExtractMoneyNotEnough
	}
	extract := &entity.WarehouseMoneyExtract{
		UID:         uid,
		WID:         material.ID,
		TypeID:      material.TypeID,
		TypeName:    material.Types.Name,
		TypeImg:     material.Types.Img,
		TypeModule:  material.Types.Module,
		Name:        req.Name,
		BankCardNum: req.Code,
		Money:       req.Num,
		Status:      0,
		AddTime:     time.Now().Format(time.DateTime),
	}
	return w.warehouseDao.WarehouseExtract(ctx, material, extract)
}

func (w *WarehouseService) CardBuyCount(ctx context.Context, uid uint) int64 {
	return w.warehouseDao.CardBuyCount(ctx, uid)
}
func NewWarehouseService(r *repo.Manager) *WarehouseService {
	return &WarehouseService{
		warehouseDao: dao.NewWarehouseDao(r),
		userDao:      dao.NewUserDao(r),
		typeDao:      dao.NewTypeDao(r),
		configDao:    dao.NewConfigDao(r),
	}
}
